Skip to content

Nas backup: Allow credentials in backup repository mount options for cifs mount - #14009

Open
abh1sar wants to merge 3 commits into
apache:4.20from
shapeblue:nas-cifs-mount
Open

abh1sar wants to merge 3 commits into
apache:4.20from
shapeblue:nas-cifs-mount

Conversation

@abh1sar

@abh1sar abh1sar commented Aug 29, 2026 •

Copy link
Copy Markdown
Contributor

Description

The SafeCommandOptions whitelist added for command injection hardening in 56ad044 only accepts [A-Za-z0-9,._=:/+-] and whitespace.
Mount options are how credentials reach a CIFS backup repository, and any realistic value is rejected: an Active Directory username such as user@domain, or a password containing @ ! # % ^ ~. Adding or updating such a repository fails with "contains unsupported or unsafe characters".

The list is now parsed for what it is, a comma separated list of "key" or "key=value" entries, with the punctuation that appears in credentials allowed in values only. It is not a loosening across the board. Keys keep the old restrictive character set, and everything the shell treats specially or expands is still rejected in both: whitespace, quotes, $ ` ; | & < > ( ) { } [ ] \ and the glob characters * and ?. Whitespace was previously accepted and is not any more, since that is what would let a value turn into extra mount arguments.

nasbackup.sh interpolated the options into the mount command unquoted, so a value containing whitespace or a glob was split or expanded by the shell before mount saw it. The command is now built as an array and the options passed as a single quoted argument, so the option list cannot influence anything but the -o argument regardless of what validation allows through.

Not that this doesn't affect existing repositories, only the new ones.

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (improves an existing feature and functionality)
  • Cleanup (Code refactoring and cleanup, that may add test cases)
  • Build/CI
  • Test (unit or integration test code)

Feature/Enhancement Scale or Bug Severity

Feature/Enhancement Scale

  • Major
  • Minor

Bug Severity

  • BLOCKER
  • Critical
  • Major
  • Minor
  • Trivial

Screenshots (if appropriate):

How Has This Been Tested?

How did you try to break this feature and the system with this change?

@abh1sar

abh1sar commented Aug 29, 2026

Copy link
Copy Markdown
Contributor Author

@blueorangutan package

@abh1sar
abh1sar requested review from shwstppr and weizhouapache and a lite review from Copilot August 29, 2026 16:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates CloudStack’s handling of backup repository mount options so CIFS credentials (and similar secrets like cephx keys) can be provided safely, without reintroducing command injection risk.

Changes:

  • Replaces the overly restrictive SafeCommandOptions validation with a mount-options–aware validator (SafeMountCommandOptions) that allows common credential punctuation in values while keeping option keys restrictive.
  • Updates KVM nasbackup.sh to construct the mount command as an argument array and pass -o options as a single quoted argument.
  • Extends ParamProcessWorkerTest coverage for accepted/rejected mount option patterns (credentials punctuation, base64-like values, and unsafe tokens).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
api/src/main/java/org/apache/cloudstack/api/ApiArgValidator.java Introduces SafeMountCommandOptions with key/value-aware parsing and tighter validation rules.
api/src/main/java/org/apache/cloudstack/api/command/user/backup/repository/AddBackupRepositoryCmd.java Switches mountOptions validation to SafeMountCommandOptions.
api/src/main/java/org/apache/cloudstack/api/command/user/backup/repository/UpdateBackupRepositoryCmd.java Switches mountOptions validation to SafeMountCommandOptions.
server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java Routes the new validator in parameter validation dispatch.
server/src/test/java/com/cloud/api/dispatch/ParamProcessWorkerTest.java Adds tests for credential-friendly mount options and rejection of unsafe patterns.
scripts/vm/hypervisor/kvm/nasbackup.sh Builds mount invocation via an array and passes options as a single argument to avoid shell splitting/expansion.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread scripts/vm/hypervisor/kvm/nasbackup.sh Resolved
@codecov

codecov Bot commented Aug 29, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 58.33333% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 16.41%. Comparing base (9c8bdf3) to head (bd9b559).
⚠️ Report is 13 commits behind head on 4.20.

Files with missing lines Patch % Lines
...ava/org/apache/cloudstack/api/ApiArgValidator.java 63.63% 3 Missing and 1 partial ⚠️
...ava/com/cloud/api/dispatch/ParamProcessWorker.java 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               4.20   #14009      +/-   ##
============================================
+ Coverage     16.35%   16.41%   +0.05%     
- Complexity    13587    13656      +69     
============================================
  Files          5669     5669              
  Lines        501474   501632     +158     
  Branches      60913    60943      +30     
============================================
+ Hits          82030    82328     +298     
+ Misses       410251   410077     -174     
- Partials       9193     9227      +34     
Flag Coverage Δ
uitests 4.16% <ø> (+0.02%) ⬆️
unittests 17.27% <58.33%> (+0.05%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@DaanHoogland

Copy link
Copy Markdown
Contributor

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@DaanHoogland a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 19037

@abh1sar abh1sar changed the title Allow credentials in backup repository mount options for cifs mount Nas backup: Allow credentials in backup repository mount options for cifs mount Sep 3, 2026

@weizhouapache weizhouapache left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@abh1sar
code lgtm

will it cause potential security issue ? I have not checked

@abh1sar

abh1sar commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor Author

@abh1sar code lgtm

will it cause potential security issue ? I have not checked

@weizhouapache No, it shouldn't. everything the shell treats specially or expands is still rejected.

@shwstppr can you please also take a look

@shwstppr

shwstppr commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@shwstppr a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@shwstppr shwstppr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check if 4.20 also needs changes.
Changes look good

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 19174

@abh1sar

abh1sar commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@abh1sar a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

Validation returned early for a blank value, so a list of nothing but whitespace
was accepted although whitespace is rejected everywhere else in the list. The
two sides then disagreed about it: the restore wrapper treats it as no options
at all, while the backup script sees a non empty string and hands it to mount as
an option of its own. An empty value still clears the options, anything else is
now validated.

The array holding the mount command is also declared local, as arrays assigned
in a bash function are otherwise global. mount_point and dest stay as they are,
the callers of mount_operation read them.
@abh1sar

abh1sar commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@abh1sar a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 19180

@weizhouapache

Copy link
Copy Markdown
Member

@blueorangutan test

@blueorangutan

Copy link
Copy Markdown

@weizhouapache a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests

@blueorangutan

Copy link
Copy Markdown

[SF] Trillian Build Failed (tid-16958)

@abh1sar

abh1sar commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

@blueorangutan test

@blueorangutan

Copy link
Copy Markdown

@abh1sar a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests

@blueorangutan

Copy link
Copy Markdown

[SF] Trillian test result (tid-16967)
Environment: kvm-ol8 (x2), zone: Advanced Networking with Mgmt server ol8
Total time taken: 52942 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr14009-t16967-kvm-ol8.zip
Smoke tests completed. 141 look OK, 0 have errors, 0 did not run
Only failed and skipped tests results shown below:

Test Result Time (s) Test File

@RosiKyu RosiKyu assigned RosiKyu and unassigned RosiKyu Oct 8, 2026
Comment thread scripts/vm/hypervisor/kvm/nasbackup.sh Resolved
Comment thread scripts/vm/hypervisor/kvm/nasbackup.sh Resolved
…f stdout

$? after the pipe is the status of tee, so a failed mount was treated as mounted. Read the
status of mount from PIPESTATUS instead. Send the stderr of mount to the agent log rather than
stdout, since the agent parses every stdout line of a stopped VM backup as a size.
@abh1sar

abh1sar commented Oct 12, 2026

Copy link
Copy Markdown
Contributor Author

@blueorangutan package

@Damans227 Damans227 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @abh1sar, fix looks right. LGTM

@abh1sar

abh1sar commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

@blueorangutan test

@blueorangutan

Copy link
Copy Markdown

@abh1sar a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests

@blueorangutan

Copy link
Copy Markdown

[SF] Trillian test result (tid-17126)
Environment: kvm-ol8 (x2), zone: Advanced Networking with Mgmt server ol8
Total time taken: 55768 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr14009-t17126-kvm-ol8.zip
Smoke tests completed. 140 look OK, 1 have errors, 0 did not run
Only failed and skipped tests results shown below:

Test Result Time (s) Test File
test_01_redundant_vpc_site2site_vpn Failure 460.45 test_vpc_vpn.py

@RosiKyu

RosiKyu commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@RosiKyu a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 19682

@RosiKyu RosiKyu left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested the PR on KVM on Oracle Linux 9, NFS and CIFS backup repositories. The environment was deployed with 4.20.0.0 and upgraded to the PR build.

New repositories work as expected: whitespace and unsafe characters are rejected when a repository is added. Repositories that were created before the upgrade still fail, so the ticket scenario is not fixed for existing users.

1. Restore still fails for a repository created before the upgrade

Preconditions

  • A NAS backup repository was added on 4.20.0.0 with a trailing space in the mount options (vers=4.1 ).
  • A VM is assigned to an offering on that repository and has a backup.
  • The management server and the KVM agents are upgraded to the PR build.
  • The VM is stopped.

Steps and what each one shows

Step 1. Check the installed build and when it was installed.

Shows: the PR build was installed on 22 Oct 2026 at 16:12:59 UTC.

[root@ref-trl-12527-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# rpm -q --last cloudstack-management
cloudstack-management-4.20.4.0-shapeblue22218.noarch Thu 22 Oct 2026 04:12:59 PM UTC

Step 2. Find the request that created the repository.

Shows: the repository was added on 22 Oct 2026 at 12:57:14 UTC, before the upgrade, with mountopts=vers%3D4.1%20. That is vers=4.1 followed by a space (%20).

[root@ref-trl-12527-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# grep -F 'name=p14009-nfs-trail' /var/log/cloudstack/management/access.log | grep -o '^[^"]*"GET [^ ]*addBackupRepository[^ ]*'
10.0.33.194 - - [22/Oct/2026:12:57:14 +0000] "GET /client/api?address=10.0.32.4%3A%2Facs%2Fprimary%2Fref-trl-12527-k-Mol9-rositsa-kyuchukova%2Fp14009-nasbackup&apiKey=<masked>&command=addBackupRepository&mountopts=vers%3D4.1%20&name=p14009-nfs-trail&provider=nas&response=json&type=nfs&zoneid=542bd679-6186-4023-b58b-04b6957a6bcf&signature=<masked>

Step 3. Check that the repository still exists after the upgrade.

Shows: the repository is listed and looks healthy.

[root@ref-trl-12527-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk list backuprepositories name=p14009-nfs-trail filter=id,name,type,address
{
  "backuprepository": [
    {
      "address": "10.0.32.4:/acs/primary/ref-trl-12527-k-Mol9-rositsa-kyuchukova/p14009-nasbackup",
      "id": "f3bc71a5-4f27-4f1b-a929-3fd579ab25b0",
      "name": "p14009-nfs-trail",
      "type": "nfs"
    }
  ],
  "count": 1
}

Step 4. Check the VM.

Shows: the VM uses an offering on this repository and is stopped, so it can be restored.

[root@ref-trl-12527-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk list virtualmachines id=dc12845e-cb24-4207-8f28-348905b51b7d filter=name,instancename,state,backupofferingname
{
  "count": 1,
  "virtualmachine": [
    {
      "backupofferingname": "p14009-off-nfs-trail",
      "instancename": "i-2-6-VM",
      "name": "p14009-vm2",
      "state": "Stopped"
    }
  ]
}

Step 5. Restore the backup.

Shows: the restore fails with error 530.

[root@ref-trl-12527-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk restore backup id=fa436be9-dce4-453b-934c-5d948b707f5c
{
  "account": "admin",
  "accountid": "043319d2-cdfd-11f1-9e4d-1e00bd000255",
  "cmd": "org.apache.cloudstack.api.command.user.backup.RestoreBackupCmd",
  "completed": "2026-10-26T07:32:54+0000",
  "created": "2026-10-26T07:32:54+0000",
  "domainid": "af3b2b20-cdfc-11f1-9e4d-1e00bd000255",
  "domainpath": "ROOT",
  "jobid": "a9956a66-04b9-419e-bc10-9f3700a5d5e7",
  "jobprocstatus": 0,
  "jobresult": {
    "errorcode": 530,
    "errortext": "Error restoring VM from backup [{\"date\":\"Thu Oct 22 17:26:25 UTC 2026\",\"externalId\":\"i-2-6-VM\\/2026.10.22.17.25.27\",\"status\":\"BackedUp\",\"uuid\":\"fa436be9-dce4-453b-934c-5d948b707f5c\",\"vmId\":6}]."
  },
  "jobresultcode": 530,
  "jobresulttype": "object",
  "jobstatus": 2,
  "userid": "0433eb46-cdfd-11f1-9e4d-1e00bd000255"
}
🙈 Error: async API failed for job a9956a66-04b9-419e-bc10-9f3700a5d5e7

Step 6. Check the agent log on the KVM host that ran the restore.

Shows: at the same time as the failed job (07:32:53), the agent ran mount with -o vers=4.1 (with the trailing space), and mount rejected it with "parsing error on 'vers=' option".

[root@ref-trl-12527-k-Mol9-rositsa-kyuchukova-kvm2 ~]# grep -F 'encountered the error: [mount.nfs: parsing error' /var/log/cloudstack/agent/agent.log
2026-10-26 07:32:53,861 WARN  [utils.script.Script] (AgentRequest-Handler-2:[]) (logid:) Process [302147] for command [sudo /usr/bin/mount -t nfs 10.0.32.4:/acs/primary/ref-trl-12527-k-Mol9-rositsa-kyuchukova/p14009-nasbackup /usr/share/cloudstack-agent/tmp/csbackup.bcbbw10022181143658018877 -o vers=4.1  ] encountered the error: [mount.nfs: parsing error on 'vers=' option].

Expected result

The restore succeeds. This is the scenario of the ticket: restore fails when the mount options have trailing whitespace.

Actual result

The restore fails with error 530 "Error restoring VM from backup". The mount options stored before the upgrade still contain the trailing space, and mount rejects them. On 4.20 there is no API to edit the mount options of an existing repository, so the user cannot correct the value.

Same result on a CIFS repository

A CIFS repository p14009-cifs-trail was also added on 4.20.0.0 with a trailing space at the end of its mount options (username=...,password=...,vers=3.0,nobrl ). Restoring its backup on the PR build fails in the same way.

Step 7. Check the VM of the CIFS repository.

Shows: the VM is stopped, so it can be restored.

[root@ref-trl-12527-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk list virtualmachines name=p14009-vm4 filter=id,state
{
  "count": 1,
  "virtualmachine": [
    {
      "id": "dacdbaf5-a752-4b9e-b8d0-c74d91aac8d3",
      "state": "Stopped"
    }
  ]
}

Step 8. Restore the backup.

Shows: the restore fails with error 530.

[root@ref-trl-12527-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk restore backup id=144d316b-1064-4db7-adb9-3094dc4d612f
{
  "account": "admin",
  "accountid": "043319d2-cdfd-11f1-9e4d-1e00bd000255",
  "cmd": "org.apache.cloudstack.api.command.user.backup.RestoreBackupCmd",
  "completed": "2026-10-26T07:39:38+0000",
  "created": "2026-10-26T07:39:37+0000",
  "domainid": "af3b2b20-cdfc-11f1-9e4d-1e00bd000255",
  "domainpath": "ROOT",
  "jobid": "681e7196-4c9d-472e-9c15-797c9c436c45",
  "jobprocstatus": 0,
  "jobresult": {
    "errorcode": 530,
    "errortext": "Error restoring VM from backup [{\"date\":\"Thu Oct 22 13:06:09 UTC 2026\",\"externalId\":\"i-2-8-VM\\/2026.10.22.13.04.16\",\"status\":\"BackedUp\",\"uuid\":\"144d316b-1064-4db7-adb9-3094dc4d612f\",\"vmId\":8}]."
  },
  "jobresultcode": 530,
  "jobresulttype": "object",
  "jobstatus": 2,
  "userid": "0433eb46-cdfd-11f1-9e4d-1e00bd000255"
}
🙈 Error: async API failed for job 681e7196-4c9d-472e-9c15-797c9c436c45

Step 9. Check the agent log on the KVM host that ran the restore.

Shows: the stored options still end with a space (nobrl ,nobrl: the space comes before the ,nobrl that is added for CIFS), and mount rejects them with "mount error(22): Invalid argument".

[root@ref-trl-12527-k-Mol9-rositsa-kyuchukova-kvm1 ~]# grep -F 'encountered the error: [mount error(22)' /var/log/cloudstack/agent/agent.log
2026-10-26 07:39:38,104 WARN  [utils.script.Script] (AgentRequest-Handler-1:[]) (logid:) Process [337585] for command [sudo /usr/bin/mount -t cifs //10.0.53.204/backup /usr/share/cloudstack-agent/tmp/csbackup.rWTab12658000772677188172 -o username=root,password=<masked>,vers=3.0,nobrl ,nobrl ] encountered the error: [mount error(22): Invalid argumentRefer to the mount.cifs(8) manual page (e.g. man mount.cifs) and kernel log messages (dmesg)].

2. Backup and delete fail after the upgrade (regression)

Preconditions

The same repository and VM as in 1 (p14009-nfs-trail, p14009-vm2). On 4.20.0.0, backup from this repository worked.

Steps and what each one shows

Step 1. Take a backup of the VM.

Shows: the backup fails with error 530.

[root@ref-trl-12527-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk create backup virtualmachineid=dc12845e-cb24-4207-8f28-348905b51b7d
{
  "account": "admin",
  "accountid": "043319d2-cdfd-11f1-9e4d-1e00bd000255",
  "cmd": "org.apache.cloudstack.api.command.user.backup.CreateBackupCmd",
  "completed": "2026-10-26T07:37:40+0000",
  "created": "2026-10-26T07:37:40+0000",
  "domainid": "af3b2b20-cdfc-11f1-9e4d-1e00bd000255",
  "domainpath": "ROOT",
  "jobid": "a7727e6b-fceb-4ca4-bcd9-cfd06be41598",
  "jobinstancetype": "Backup",
  "jobprocstatus": 0,
  "jobresult": {
    "errorcode": 530,
    "errortext": "Failed to create VM backup"
  },
  "jobresultcode": 530,
  "jobresulttype": "object",
  "jobstatus": 2,
  "userid": "0433eb46-cdfd-11f1-9e4d-1e00bd000255"
}
🙈 Error: async API failed for job a7727e6b-fceb-4ca4-bcd9-cfd06be41598

Step 2. Delete an existing backup of the VM.

Shows: the delete fails with error 530.

[root@ref-trl-12527-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# cmk delete backup id=fa436be9-dce4-453b-934c-5d948b707f5c
{
  "account": "admin",
  "accountid": "043319d2-cdfd-11f1-9e4d-1e00bd000255",
  "cmd": "org.apache.cloudstack.api.command.user.backup.DeleteBackupCmd",
  "completed": "2026-10-26T07:37:52+0000",
  "created": "2026-10-26T07:37:52+0000",
  "domainid": "af3b2b20-cdfc-11f1-9e4d-1e00bd000255",
  "domainpath": "ROOT",
  "jobid": "71d7513c-293a-4fe6-9c4c-2db0854ae2d8",
  "jobprocstatus": 0,
  "jobresult": {
    "errorcode": 530,
    "errortext": "Failed to delete the backup"
  },
  "jobresultcode": 530,
  "jobresulttype": "object",
  "jobstatus": 2,
  "userid": "0433eb46-cdfd-11f1-9e4d-1e00bd000255"
}
🙈 Error: async API failed for job 71d7513c-293a-4fe6-9c4c-2db0854ae2d8

Step 3. Check the agent log on the KVM host.

Shows: line 55334 is the restore from section 1. For the backup (07:37:39) and the delete (07:37:52), the mount fails with the same "parsing error on 'vers=' option", and the agent answers "Failed to mount nfs store".

[root@ref-trl-12527-k-Mol9-rositsa-kyuchukova-kvm2 ~]# grep -nE 'mount.nfs: parsing error|Failed to mount nfs store' /var/log/cloudstack/agent/agent.log
55334:2026-10-26 07:32:53,861 WARN  [utils.script.Script] (AgentRequest-Handler-2:[]) (logid:) Process [302147] for command [sudo /usr/bin/mount -t nfs 10.0.32.4:/acs/primary/ref-trl-12527-k-Mol9-rositsa-kyuchukova/p14009-nasbackup /usr/share/cloudstack-agent/tmp/csbackup.bcbbw10022181143658018877 -o vers=4.1  ] encountered the error: [mount.nfs: parsing error on 'vers=' option].
55986:mount.nfs: parsing error on 'vers=' option
55988:2026-10-26 07:37:39,814 DEBUG [resource.wrapper.LibvirtTakeBackupCommandWrapper] (AgentRequest-Handler-5:[]) (logid:) Failed to take VM backup: Failed to mount nfs store
55990:2026-10-26 07:37:39,815 DEBUG [cloud.agent.Agent] (AgentRequest-Handler-5:[]) (logid:) Seq 2-6594958704330689710:  { Ans: , MgmtId: 32988519727701, via: 2, Ver: v1, Flags: 110, [{"org.apache.cloudstack.backup.BackupAnswer":{"result":"false","details":"Failed to mount nfs store","wait":"0","bypassHostMaintenance":"false"}}] }
55995:mount.nfs: parsing error on 'vers=' option
55997:2026-10-26 07:37:52,391 DEBUG [resource.wrapper.LibvirtDeleteBackupCommandWrapper] (AgentRequest-Handler-3:[]) (logid:) Backup delete result: Failed to mount nfs store
55999:2026-10-26 07:37:52,391 DEBUG [resource.wrapper.LibvirtDeleteBackupCommandWrapper] (AgentRequest-Handler-3:[]) (logid:) Failed to delete VM backup: Failed to mount nfs store
56001:2026-10-26 07:37:52,391 DEBUG [cloud.agent.Agent] (AgentRequest-Handler-3:[]) (logid:) Seq 2-6594958704330689711:  { Ans: , MgmtId: 32988519727701, via: 2, Ver: v1, Flags: 110, [{"org.apache.cloudstack.backup.BackupAnswer":{"result":"false","details":"Failed to mount nfs store

Step 4. List the backups of the VM in the database.

Shows:

  • Row 2: a backup from the same repository succeeded on 22 Oct at 13:00:29, on 4.20.0.0, before the upgrade (16:12:59). It was deleted later during testing.
  • Rows 10, 11, 20 and 54: backups that failed on the PR build. Row 54 is the backup from step 1. Each failed backup leaves a row in BackingUp state.
  • Row 18: the backup from step 2 is still there (it could not be deleted). It was taken on the PR build during testing, while the stored value was temporarily changed to vers=4.1 without the space. The value was then set back to vers=4.1 .
[root@ref-trl-12527-k-Mol9-rositsa-kyuchukova-mgmt1 ~]# mysql -uroot -p cloud -t -e "select id,uuid,status,external_id,date,removed from backups where vm_id=(select id from vm_instance where
> uuid='dc12845e-cb24-4207-8f28-348905b51b7d') order by id;"
Enter password: 
+----+--------------------------------------+-----------+------------------------------+---------------------+---------------------+
| id | uuid                                 | status    | external_id                  | date                | removed             |
+----+--------------------------------------+-----------+------------------------------+---------------------+---------------------+
|  2 | 31834206-11f3-4005-bb4c-6210ced0424a | BackedUp  | i-2-6-VM/2026.10.22.12.59.38 | 2026-10-22 13:00:29 | 2026-10-22 17:26:28 |
| 10 | 5d2effd7-ce14-41bb-a2e1-78cc1ef6bb11 | BackingUp | i-2-6-VM/2026.10.22.17.14.31 | 2026-10-22 17:14:31 | 2026-10-22 17:14:31 |
| 11 | 9af56945-b574-49cd-89eb-8caca78b17f7 | BackingUp | i-2-6-VM/2026.10.22.17.17.01 | 2026-10-22 17:17:01 | 2026-10-22 17:17:01 |
| 18 | fa436be9-dce4-453b-934c-5d948b707f5c | BackedUp  | i-2-6-VM/2026.10.22.17.25.27 | 2026-10-22 17:26:25 | NULL                |
| 20 | 2495dff4-67be-4bdd-a6e4-8d9f5f2150f4 | BackingUp | i-2-6-VM/2026.10.22.17.36.06 | 2026-10-22 17:36:07 | 2026-10-22 17:36:07 |
| 54 | d7ef169c-8902-4a26-841d-046ba34fbf33 | BackingUp | i-2-6-VM/2026.10.26.07.37.39 | 2026-10-26 07:37:40 | 2026-10-26 07:37:40 |
+----+--------------------------------------+-----------+------------------------------+---------------------+---------------------+

Expected result

Backup and delete keep working after the upgrade, as they did on 4.20.0.0 with the same repository.

Actual result

Both fail with error 530 ("Failed to create VM backup", "Failed to delete the backup"), because mount rejects the stored options with "parsing error on 'vers=' option". Before the upgrade, backups from this repository succeeded, so the PR breaks backup and delete for existing repositories. Scheduled backups stop, and old backups cannot be deleted.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

8 participants